<template>
  <draggable :class="draggableClass"
:model-value="nodes"
:group="group"
@start="onDragStart"
@end="onDragEnd"
    @move="onMove"
:data-parent-id="parentId">
    <template #item="{ element,index }">
      <div class="tree-node" :class="childrenClass(level,index,element)" :data-id="element.id">
        <span class="node-label">{{ element.label }}</span>
        <TreeDraggable v-if="element.children && element.children.length"
:nodes="element.children"
:group="group"
          :level="level + 1"
@node-dragged="nodeDragged"
:parent-id="element.id"
@changeDragging="changeDragging" />
      </div>
    </template>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: {
    draggable
  },
  watch: {
    nodes: {
      handler() {
        this.treeData = this.nodes;
      },
      deep: true
    },
  },
  data() {
    return {
    }
  },
  props: {
    dragging: {
      type: Boolean,
      required: false
    },
    parentId: {
      type: String,
      required: false
    },
    nodes: {
      type: Array,
      required: true
    },
    group: {
      type: String,
      required: true
    },
    level: {
      type: Number,
      default: 0
    }
  },
  computed: {
    draggableClass() {
      return {
        dragging: this.dragging,
        ['level-' + this.level]: true
      }
    },
    childrenClass() {
      return (level,index,element) => {
        return {
          'not-moved': element.move === false,
          ['level-' + level + '-' + index]: true
        }
      }
    }
  },
  methods: {
    changeDragging(flag) {
      this.$emit('changeDragging',flag)
    },
    onDragStart(evt) {
      this.changeDragging(true)
      console.log('Drag started',evt);
    },
    onDragEnd(evt) {
      this.changeDragging(false)
      // this.dragging = false
      const [_level,level,index] = evt.item.classList[1].split('-')
      const sourceParentId = evt.from.dataset.parentId;
      const targetParentId = evt.to.dataset.parentId;
      const newLevel = evt.to.className.split('-')[1]
      const { oldDraggableIndex,newDraggableIndex } = evt;
      console.log('Drag ended',evt);
      this.$emit('node-dragged',{
        level,index,
        newLevel,
        newDraggableIndex,sourceParentId,targetParentId
      });

    },
    onMove(evt) {
      // console.log('Dragging...',evt);
    },
    nodeDragged(data) {
      this.$emit('node-dragged',data);
    }
  },
  created() {
    this.treeData = this.nodes;
  },
  emits: ['node-dragged','changeDragging']
};
</script>
<style lang="less">
.tree-node {
  position: relative;
  width: 200px;
}

.level-0 {
  display: flex;
  flex-direction: row;
  padding: 0;
  margin: 0;
  list-style-type: none;

  &.dragging {
    .level-1 {
      display: block;
    }
  }

  &:hover {
    .level-1 {
      display: block;
    }
  }
}

.node-label:hover {
  &+.level-1 {
    display: block;
  }
}

.level-1 {
  position: absolute;
  display: none;
  border: 1px solid #ddd;
}

.level-2 {
  padding-left: 1rem;
}

.not-moved {
  color: gray;
  pointer-events: none;
}
</style>